/*
 * Copyright © 2004-2014 chenYuan. All rights reserved.
 * @Website:wwww.jspx.net
 * @Mail:39793751@qq.com
 * @author: chenYuan , 陈原
 * @License: Jspx.net Framework Code is open source (LGPL)，Jspx.net Framework 使用LGPL 开源授权协议发布。
 * @jvm:jdk1.6+  x86/amd64
 *
 */
package com.jspx.txweb.result;

import com.jspx.boot.sign.HttpStatusType;
import com.jspx.scriptmark.load.AbstractSource;
import com.jspx.security.utils.EncryptUtil;
import com.jspx.txweb.ActionInvocation;
import com.jspx.txweb.dispatcher.Dispatcher;
import com.jspx.txweb.support.ActionSupport;
import com.jspx.txweb.util.TXWebUtil;
import com.jspx.utils.ArrayUtil;
import com.jspx.utils.StringUtil;
import com.jspx.scriptmark.core.ScriptMarkEngine;
import com.jspx.scriptmark.ScriptMark;
import com.jspx.scriptmark.ScriptmarkEnv;
import com.jspx.scriptmark.config.TemplateConfigurable;
import com.jspx.scriptmark.load.FileSource;
import com.jspx.boot.environment.EnvironmentTemplate;
import com.jspx.boot.environment.Environment;
import com.jspx.boot.EnvFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User:chenYuan (mail:39793751@qq.com)
 * Date: 2006-12-27
 * Time: 21:58:28
 * com.jspx.txweb.result.TemplateResult
 *  最基本的返回输出方式，将模板文件执行后输出
 */
public class TemplateResult extends ResultSupport {
    private final static Logger log = LoggerFactory.getLogger(TemplateResult.class);

    private final static EnvironmentTemplate envTemplate = EnvFactory.getEnvironmentTemplate();
    private final static String defaultEncode = envTemplate.getString(Environment.encode, Environment.defaultEncode);
    private final static String templatePath = envTemplate.getString(Environment.templatePath);

    private static TemplateConfigurable configurable = new TemplateConfigurable();
    static
    {
        configurable.addAutoIncludes(envTemplate.getString(Environment.autoIncludes));
    }

    public TemplateResult() {

    }

    public void execute(ActionInvocation actionInvocation) throws Exception {
        ActionSupport action = actionInvocation.getActionProxy().getAction();
        HttpServletResponse response = action.getResponse();

        //浏览器缓存控制begin
        checkCache(action,response);
        //浏览器缓存控制end

        String contentType = action.getEnv(ActionSupport.ContentType);
        if (!StringUtil.isNULL(contentType)) {
            response.setContentType(contentType);
            String tempEncode = StringUtil.substringAfterLast(StringUtil.replace(contentType, " ", ""), "charset=");
            if (!StringUtil.isNULL(tempEncode))
                response.setCharacterEncoding(tempEncode);
        } else {
            String actionName = action.getEnv(ActionSupport.Key_ActionName);
            String fileType = StringUtil.substringAfterLast(actionName, ".");
            if (StringUtil.hasLength(fileType)) {
                if ("js".equalsIgnoreCase(fileType))
                    response.setContentType("text/javascript; charset=" + Dispatcher.getEncode());
                if (ArrayUtil.inArray(new String[]{"mp4", "flv", "avi", "mp3", "rmvb"}, fileType, true))
                    response.setContentType("video/" + fileType);
                if ("bt".equalsIgnoreCase(fileType)) response.setContentType("application/x-bittorrent");
                if (ArrayUtil.inArray(new String[]{"xls", "xlsx"}, fileType, true))
                    response.setContentType("application/vnd.ms-excel");
                if (ArrayUtil.inArray(new String[]{"doc", "docx"}, fileType, true))
                    response.setContentType("application/msword");
                if (ArrayUtil.inArray(new String[]{"mdb", "mdbx"}, fileType, true))
                    response.setContentType("application/msword");
                if (ArrayUtil.inArray(new String[]{"xml", "vml"}, fileType, true))
                    response.setContentType("application/xml");
                if (ArrayUtil.inArray(new String[]{"bmp", "jpg", "gif", "jpg", "png"}, fileType, true))
                    response.setContentType("image/" + fileType);
            }
            else response.setContentType("text/html; charset=" + Dispatcher.getEncode());
            response.setCharacterEncoding(Dispatcher.getEncode());
        }

        //请求编码end

        //处理下载情况 begin
        String disposition = action.getEnv(ActionSupport.Content_Disposition);
        if (!StringUtil.isNULL(disposition)) {
            response.setHeader(ActionSupport.Content_Disposition, disposition);
        }
        //处理下载情况 end
        //如果 resultConfig 里边有明确的返回，先使用明确的返回
        File f;
        if (getResultConfig()==null)
        {
            f =  new File(action.getTemplatePath(),action.getTemplateFile());
        } else {
            //这里有个路径问题 /的就直接从根目录开始,有个目录拼接的过程
            String confFile = EnvFactory.getPlaceholder().processTemplate(action.getEnv(),StringUtil.trim(getResultConfig().getValue()));
            if (confFile.startsWith("/"))
                f = new File(Dispatcher.getRealPath(),confFile);
            else
                f = new File(action.getTemplatePath(),confFile);
        }
        AbstractSource fileSource = new FileSource(f,action.getTemplateFile(), defaultEncode);
        //如果使用cache 就使用uri

        String cacheKey = ScriptmarkEnv.noCache;
        if (!envTemplate.getBoolean(Environment.logJspxDebug)) {
            cacheKey = EncryptUtil.getMd5(f.getAbsolutePath()); //为了防止特殊符号错误，转换为md5 格式
        }
        configurable.setSearchPath(new String[]{action.getTemplatePath(), Dispatcher.getRealPath(), templatePath});
        ScriptMark scriptMark;
        try {
            scriptMark = new ScriptMarkEngine(cacheKey, fileSource, configurable);
        } catch (Exception e) {
            log.debug("template file not found:" + f.getAbsolutePath(),e);
            if (debug)
            {
                TXWebUtil.errorPrint("template file not found:" + f.getAbsolutePath()+ "\r\n"+ e.getLocalizedMessage(),response,HttpStatusType.HTTP_status_404);
            } else
            {
                TXWebUtil.errorPrint("file not found,不存在的文件",response, HttpStatusType.HTTP_status_404);
            }
            return;
        }
        scriptMark.setRootDirectory(Dispatcher.getRealPath());
        scriptMark.setCurrentPath(action.getTemplatePath());
        //输出模板数据
        if (action.isProcess()) {
            Map<String, Object> valueMap = action.getEnv();
            initPageEnvironment(action,valueMap);
            if (debug)
            {
                StringWriter out = new StringWriter();
                scriptMark.process(out, valueMap);
                PrintWriter writer = response.getWriter();
                writer.print(out.toString());
                writer.flush();
                writer.close();
                out.close();
            } else
            {
                PrintWriter writer = response.getWriter();
                scriptMark.process(writer, valueMap);
                writer.close();
            }
        }
    }
}